Invalid Cookie Header returned by GET controller in both POSTMAN and Insomnia - spring-boot

I have the following Spring controller class:
#CrossOrigin
#RestController
#Slf4j
public class RcmApi extends ApiController {
#Value("${rcmRestApiServer}")
private String rcmRestApiServer;
#GetMapping(value = "/rcm/api/v1/matter/{matterId}", produces = "application/json")
public ResponseEntity<String> getMatter(#PathVariable String matterId) throws Exception {
log.info("Received call to RCM api getMatter: {}", matterId);
return buildGetResponseEntity("/api/v1/cases/" + matterId + "/aggregate");
}
private ResponseEntity<String> buildGetResponseEntity(String target) throws Exception {
return buildResponseEntity(
new HttpGet(rcmRestApiServer + target), HttpClientBuilder.create().build());
}
}
The method buildResponseEntity() referenced by buildGetResponseEntity() is defined in the base class ApiController:
public ResponseEntity<String> buildResponseEntity(HttpUriRequest request, HttpClient client)
throws Exception {
HttpResponse response = client.execute(request);
return ResponseEntity.status(response.getStatusLine().getStatusCode())
.headers(convertHeaders(response.getAllHeaders()))
.body(EntityUtils.toString(response.getEntity()));
}
public HttpHeaders convertHeaders(Header[] responseHeaders) {
HttpHeaders headers = new HttpHeaders();
Arrays.stream(responseHeaders)
.forEach(header -> headers.add(header.getName(), header.getValue()));
return headers;
}
The String matterId that the top-level method getMatter() receives is of form uuid, e.g c445e164-842f-44ec-9e38-6ae3a99fefd8. Unfortunately, when testing this endpoint locally from my POSTMAN at localhost:8084/rcm/api/v1/matter/c445e164-842f-44ec-9e38-6ae3a99fefd8, I notice the following:
POSTMAN receives a 200 OK but with boilerplate HTML source for a redirect page.
More interestingly, the controller thread logs of an "Invalid Cookie Header" at WARN - level:
2022-07-18 20:05:52.331-04:00 INFO 60322 --- [reactor-http-nio-3] o.f.r.caseapi.gateway.controller.RcmApi : Received call to RCM api getMatter: c445e164-842f-44ec-9e38-6ae3a99fefd8
2022-07-18 20:05:56.803-04:00 WARN 60322 --- [reactor-http-nio-3] o.a.h.c.protocol.ResponseProcessCookies : Invalid cookie header: "Set-Cookie: AWSALB=pAa3xa4sTidJy1nU1HKgYZEGx55KVvoCyojb+0FWnPksfr8qSmfBLg052RiLhw7FmhDYzSxzikY7rKIhfisr6YCP08ubdoUcSjJqOf8UcndIpU7q9fQzqM13GTYA; Expires=Tue, 26 Jul 2022 00:05:54 GMT; Path=/". Invalid 'expires' attribute: Tue, 26 Jul 2022 00:05:54 GMT
2022-07-18 20:05:56.804-04:00 WARN 60322 --- [reactor-http-nio-3] o.a.h.c.protocol.ResponseProcessCookies : Invalid cookie header: "Set-Cookie: AWSALBCORS=pAa3xa4sTidJy1nU1HKgYZEGx55KVvoCyojb+0FWnPksfr8qSmfBLg052RiLhw7FmhDYzSxzikY7rKIhfisr6YCP08ubdoUcSjJqOf8UcndIpU7q9fQzqM13GTYA; Expires=Tue, 26 Jul 2022 00:05:54 GMT; Path=/; SameSite=None; Secure". Invalid 'expires' attribute: Tue, 26 Jul 2022 00:05:54 GMT
Thinking that POSTMAN was messing up the request cookie somehow, I have tried the exact same process through INSOMNIA, getting the exact same behavior. Any help appreciated.

Try to prepare your HttpClient like so:
HttpClient httpClient = HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom()
.setCookieSpec(CookieSpecs.STANDARD).build())
.build();

Related

Spring webflux: ServerResponse redirection

This is my related code:
#RestController
public class GicarController {
#PostMapping("/login")
public Mono<ServerResponse> gicar(#RequestHeader("GICAR_ID") String gicarId) {
return ServerResponse.temporaryRedirect(URI.create("/me")).build();
}
}
Issue arises when I'm calling to _/login endpoint:
$ curl -i -X POST localhost:8080/login -H "GICAR_ID: tre"
HTTP/1.1 200 OK
transfer-encoding: chunked
Content-Type: text/event-stream;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
Referrer-Policy: no-referrer
curl: (18) transfer closed with outstanding read data remaining
Why am I getting an 200 http code response?
On spring boot logging I'm getting this exception:
022-06-27 13:11:19.931 ERROR 79654 --- [or-http-epoll-2] r.n.http.server.HttpServerOperations : [9750a9d8-1, L:/127.0.0.1:8080 - R:/127.0.0.1:33150] Error finishing response. Closing connection
org.springframework.core.codec.CodecException: Type definition error: [simple type, class org.springframework.web.reactive.function.server.DefaultServerResponseBuilder$WriterFunctionResponse]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.springframework.web.reactive.function.server.DefaultServerResponseBuilder$WriterFunctionResponse and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
Why above exception is reaised?
Any ideas?
According to Spring documentation ServerResponse
Represents a typed server-side HTTP response, as returned by a handler function or filter function.
and it supposed to be used in Functional Endpoints
#Configuration
public class GicarConfiguration {
#Bean
public RouterFunction<ServerResponse> route() {
return RouterFunctions
.route(POST("/login"), this::loginHandler);
}
private Mono<ServerResponse> loginHandler(ServerRequest request) {
var gicarId = request.headers().firstHeader("GICAR_ID");
return ServerResponse.temporaryRedirect(URI.create("/me")).build();
}
}
If you still want to use Annotated Controllers, use ResponseEntity instead
#RestController
public class GicarController {
#PostMapping("/login")
public Mono<ResponseEntity<Void>> gicar() {
return Mono.just(ResponseEntity
.status(HttpStatus.TEMPORARY_REDIRECT)
.header(HttpHeaders.LOCATION, "/me")
.build()
);
}
}

Spring WebServiceTemplate add value to Cookie header

I have to add an information in the cookie of a request that my application sends to another application,
but it doesn't seem to be added correctly.
When I check the request with WireShark, I see two Cookie headers in the headers :
POST /service HTTP/1.1
Accept-Encoding: gzip
Cookie: iam=**************************
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: text/xml; charset=utf-8
Content-Length: 128393
Host: host-dev:9999
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.10 (Java/1.8.0_271)
Cookie: JSESSIONID=***********************
Authorization: Basic **************************
(I've changed some of the info)
In my code I have this :
#Service
public class ESignatureSoapConnector extends WebServiceGatewaySupport {
private ObjectFactory objectFactory;
#Autowired
public ESignatureSoapConnector(ESignatureMarshaller marshaller, ConfigurationProperties configurationProperties) throws Exception {
this.setMarshaller(marshaller);
this.setUnmarshaller(marshaller);
this.setDefaultUri(configurationProperties.getBaseUrl());
this.setMessageSender(buildMessageSender(configurationProperties.getUsername(), configurationProperties.getPassword()));
this.objectFactory = new ObjectFactory();
}
public ESignatureResponse signDocument(MTOMFile file, String iamCookieValue) {
ESignature request = new ESignature();
request.setInputDocument(file);
JAXBElement<ESignatureResponse> response = (JAXBElement<ESignatureResponse>) getWebServiceTemplate()
.marshalSendAndReceive(objectFactory.createESignature(request), new WebServiceMessageCallback() {
#Override
public void doWithMessage(WebServiceMessage webServiceMessage) throws IOException, TransformerException {
TransportContext context = TransportContextHolder.getTransportContext();
HttpComponentsConnection connection = (HttpComponentsConnection) context.getConnection();
HttpPost post = connection.getHttpPost();
post.addHeader("Cookie", "iam=" + iamCookieValue);
}
});
return response.getValue();
}
private WebServiceMessageSender buildMessageSender(String username, String password) throws Exception {
...
}
}
I'm assuming the way I set the cookie isn't correct but I can't find the proper way to do it.
The value for the cookie is different for each request, it's a soap request and I work in Spring
The solution we've found :
JAXBElement<ESignatureResponse> response = (JAXBElement<ESignatureResponse>) getWebServiceTemplate()
.marshalSendAndReceive(objectFactory.createESignature(request), new WebServiceMessageCallback() {
#Override
public void doWithMessage(WebServiceMessage webServiceMessage) throws IOException, TransformerException {
HttpClient httpClient = ((HttpComponentsMessageSender) getWebServiceTemplate().getMessageSenders()[0]).getHttpClient();
BasicClientCookie iamCookie = new BasicClientCookie(iamConfigurationProperties.getCookieName(), iamCookieValue);
iamCookie.setDomain(iamConfigurationProperties.getCookieDomain());
iamCookie.setPath(iamConfigurationProperties.getCookiePath());
((DefaultHttpClient) httpClient).getCookieStore().addCookie(iamCookie);
}
});

java.net.SocketException: Unexpected end of file from server using Spring's RestTemplate

I've already checked several questions / answers regarding similar subjects, but can't find the proper answer for my case.
I'm using Spring's RestTemplate but fails to get the response from a third party server with the following exception:
Exception in thread "main" org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://64.76.157.19:8283/ENAP/ProveedorExterno/v1.0/insertarUltimaPosicion":Unexpected end of file from server; nested exception is java.net.SocketException: Unexpected end of file from server
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:567)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:512)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:454)
at cl.waypoint.integracion.GenericCallback.sendEnap(GenericCallback.java:187)
at cl.waypoint.integracion.GenericCallback.main(GenericCallback.java:167)
Caused by: java.net.SocketException: Unexpected end of file from server
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:718)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:579)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1322)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:48)
at cl.waypoint.integracion.GenericCallback$LoggingRequestInterceptor.log(GenericCallback.java:229)
at cl.waypoint.integracion.GenericCallback$LoggingRequestInterceptor.intercept(GenericCallback.java:216)
at org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:84)
at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:69)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:551)
... 4 more
But when sending the same request/headers/payload using command line curl there seems to be no problem at all, this is the verbose output of it:
* Trying A.B.C.D...
* Connected to A.B.C.D (A.B.C.D) port 8283 (#0)
> POST /ENAP/ProveedorExterno/v1.0/insertarUltimaPosicion HTTP/1.1
> Host: A.B.C.D:8283
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type: application/json
> Authorization: Bearer dsgfsdgf786dsfg7dsgf
> Content-Length: 567
>
* upload completely sent off: 567 out of 567 bytes
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: POST
< Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Content-Type
< Content-Type: application/json
< Date: Wed, 27 Jul 2016 13:35:26 GMT
< Transfer-Encoding: chunked
<
* Connection #0 to host 64.76.157.19 left intact
PS: Authorization token and server's IP address have been changed for security reasons.
Spring seems to hang for a while and then then throw the exception, perhaps it's waiting for something by default...Content-Length header on the response? If so, can that be overriden?
The Exception comes from the following interceptor:
class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {
#Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
ClientHttpResponse response = execution.execute(request, body);
log(request, body, response);
return response;
}
private void log(HttpRequest request, byte[] body, ClientHttpResponse response) throws IOException {
HttpHeaders headers = request.getHeaders();
System.out.println("=============================");
for (Entry<String, List<String>> header : headers.entrySet()) {
System.out.println(header.getKey() + ": " + header.getValue());
}
System.out.println("=============================");
System.out.println(new String(body));
System.out.println(response.getRawStatusCode());
System.out.println(response.getStatusText());
}
}
Which is used from the following code snippet:
private void sendEnap(String patente, String fecha, String latitud, String longitud, BigInteger sentido,
BigInteger velocidad, int ignicion) {
RestTemplate restTemplate = new RestTemplate();
// set interceptors/requestFactory
ClientHttpRequestInterceptor ri = new LoggingRequestInterceptor();
List<ClientHttpRequestInterceptor> ris = new ArrayList<ClientHttpRequestInterceptor>();
ris.add(ri);
restTemplate.setInterceptors(ris);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Authorization", "Bearer " + ENANGAB_TOKEN);
headers.add("Content-Type", MediaType.APPLICATION_JSON.toString());
headers.add("User-Agent", "Waypoint");
EnapRequest enapRequest = new EnapRequest(patente, fecha, latitud, longitud, sentido, velocidad, ignicion);
HttpEntity<EnapRequest> request = new HttpEntity<EnapRequest>(enapRequest, headers);
ResponseEntity<EnapResponse> response = restTemplate.exchange(ENAP_ENDPOINT, HttpMethod.POST, request,
EnapResponse.class);
System.out.println(response.getBody());
}
If the interceptor is disabled, same exception arises but now with this stacktrace:
Exception in thread "main" org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://64.76.157.19:8283/ENAP/ProveedorExterno/v1.0/insertarUltimaPosicion":Unexpected end of file from server; nested exception is java.net.SocketException: Unexpected end of file from server
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:567)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:512)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:454)
at cl.waypoint.integracion.GenericCallback.sendEnap(GenericCallback.java:187)
at cl.waypoint.integracion.GenericCallback.main(GenericCallback.java:167)
Caused by: java.net.SocketException: Unexpected end of file from server
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:718)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:579)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1322)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:48)
at org.springframework.http.client.AbstractClientHttpResponse.getStatusCode(AbstractClientHttpResponse.java:33)
at org.springframework.web.client.DefaultResponseErrorHandler.getHttpStatusCode(DefaultResponseErrorHandler.java:56)
at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:50)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:552)
... 4 more
The above is another hint for a missing header on the response, don't know which one, and how to avoid such wait too.
Any hints would be appreciated
EDIT:
Headers sent:
Accept: [application/json, application/*+json]
Authorization: [Bearer dsgfsdgf786dsfg7dsgf]
Content-Type: [application/json]
User-Agent: [Waypoint]
Content-Length: [567]
EnapRequest class:
package cl.waypoint.integracion;
import java.math.BigInteger;
import com.fasterxml.jackson.annotation.JsonProperty;
public class EnapRequest {
#JsonProperty("token_proveedor")
private String tokenProveedor = GenericCallback.ENANGAB_TOKEN;
private Posicion[] posicion;
public EnapRequest(String patente, String fecha, String latitud, String longitud, BigInteger sentido,
BigInteger velocidad, int ignicion) {
posicion = new Posicion[1];
posicion[0] = new Posicion(patente, fecha, latitud, longitud, sentido, velocidad, ignicion);
}
public String getTokenProveedor() {
return tokenProveedor;
}
public void setTokenProveedor(String tokenProveedor) {
this.tokenProveedor = tokenProveedor;
}
public Posicion[] getPosicion() {
return posicion;
}
public void setPosicion(Posicion[] posicion) {
this.posicion = posicion;
}
}
The request body is in fact being sent as JSON (exactly the same as with curl, pretty print here for improved reading):
{
"posicion": [
{
"patente": "AB1234",
"latitud": "-36.752752",
"longitud": "-73.0804947",
"direccion": "120",
"velocidad": "65",
"transportista": "ENANGAB",
"sensora1": null,
"sensora2": null,
"sensora3": null,
"mopo_sensord1": null,
"mopo_sensord2": null,
"mopo_sensord3": null,
"mopo_sensord4": null,
"mopo_sensord5": null,
"mopo_sensord6": null,
"opcional1": null,
"opcional2": null,
"opcional3": null,
"opcional4": null,
"codigo_interno": null,
"fecha_hora": "2016-07-15T14:24:00",
"mopo_estado": "1",
"mopo_estado_ignicion": "1",
"moev_numero_evento": "45"
}
],
"token_proveedor": "dsgfsdgf786dsfg7dsgf"
}
The RestTemplate object has already configured support for the following converters:
class org.springframework.http.converter.ByteArrayHttpMessageConverter
class org.springframework.http.converter.StringHttpMessageConverter
class org.springframework.http.converter.ResourceHttpMessageConverter
class org.springframework.http.converter.xml.SourceHttpMessageConverter
class org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter
class org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter
class org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
I think the problem here is that your request has a wrong data type which server can not parse and thus can not reply.
Since you are sending a POST request with JSON Content-Type header, your EnapRequest must be JSON-encoded.
To do that, you need to make sure EnapRequest is a POJO class, then modify your code inside sendEnap()
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
and include Jackson libraries in the classpath
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.1</version>
</dependency>
I had the same error, check the packet size configured at the network level for the server(if there is a mismatch - the packet size expected is lesser than the packet size recieved, this error would arise)
Try running the following command on the server you are hitting:
ip addr | grep mtu

Spring/Eureka/Feign - FeignClient setting Content-Type header to application/x-www-form-urlencoded

When I use a FeignClient it is setting the Content-Type to application/x-www-form-urlencoded instead of application/json;charset=UTF-8.
If I use a RestTemplate to send the same message the message header Content-Type is correctly set to application/json;charset=UTF-8.
Both the FeignClient and RestTemplate are using Eureka for service discovery, and I discovered this problem by debugging the HTTP message received by the server.
The controller on the server side looks like this:
#RestController
#RequestMapping("/site/alarm")
public class SiteAlarmController {
#RequestMapping(method = RequestMethod.POST)
#ResponseBody
public ResponseEntity<RaiseAlarmResponseDto> raiseAlarm(#RequestBody RaiseSiteAlarmRequestDto requestDto) {
...
}
My FeignClient interface in the service that calls the alarm looks like this:
#FeignClient("alarm-service")
public interface AlarmFeignService {
#RequestMapping(method = RequestMethod.POST, value = "/site/alarm")
RaiseAlarmResponseDto raiseAlarm(#RequestBody RaiseSiteAlarmRequestDto requestDto);
}
The HTTP message headers from the FeignClient are:
Accept: */*
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.7.0_60
Host: smit005s-MacBook-Pro.local:9120
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 323
The alarm service doesn't like the Content-Type and throws the following exception:
2015-04-22 12:12:28.580 thread="qtp1774842986-25" class="org.eclipse.jetty.servlet.ServletHandler" level="WARN"
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is feign.FeignException: status 415 reading AlarmFeignService#raiseAlarm(RaiseSiteAlarmRequestDto); content:
{"timestamp":1429701148576,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Unsupported Media Type","path":"/site/alarm"}
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618) ~[tomcat-embed-core-8.0.20.jar:8.0.20]
...
... /* commented rest of stack out */
...
If I change the client side code to use a RestTemplate as follows:
#Service
public class AlarmService {
#Autowired
private RestTemplate restTemplate;
...
public void send(RaiseSiteAlarmRequestDto alarm) {
RaiseAlarmResponseDto result = restTemplate.postForObject("http://alarm-service/site/alarm",
raiseSiteAlarmRequestDto, RaiseAlarmResponseDto.class);
}
}
It works with the RestTemplate, the alarm-service receives the message and processes it successfully. The message headers sent by the RestTemplate are:
Accept: application/json, application/*+json
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.7.0_60
Host: smit005s-MacBook-Pro.local:9120
Connection: keep-alive
Content-Length: 323
The answer was to do as #spencergibb suggests; use the consumes directive in the #RequestMapping annotation on the FeignClient interface. This Spring/Netflix documentaition also has an example.
So for example the #FeignClient interface declaration in the client is now:
#FeignClient("alarm-service")
public interface AlarmFeignService {
#RequestMapping(method = RequestMethod.POST, value = "/site/alarm", consumes = "application/json"))
RaiseAlarmResponseDto raiseAlarm(RaiseSiteAlarmRequestDto requestDto);
}
Note this is only necessary on the client side and the server side controller does not need to have this change.
Would be nice if this was done by default on the #FeignClient and then it would be the consistent with RestTemplate and the server side controller #RequestMapping annotation. Maybe that can be done in a future release of spring-cloud.

Custom Header not added through apache cxf OutInterceptor with spring

I have been struggling all day to have a custom SOAP request using spring application context and apache cxf and spring.
My Interceptor class looks like below
public class HttpHeaderInterceptor extends AbstractPhaseInterceptor<Message> {
public HttpHeaderInterceptor() {
super(Phase.SETUP);
}
#Override
public void handleMessage(Message message) throws Fault {
Map<String, List<String>> ietHeaders = new HashMap<String,List<String>>();
List<String> headerItems = new LinkedList<>();
ietHeaders.put("CustomHeader", Arrays.<String>asList("myheader"));
message.put(Message.PROTOCOL_HEADERS, ietHeaders);
}
}
WHen I check with Charlesproxy it's just the normal request. I am sure I am doing something wrong. At debug time , I can step into handleMessage method but nothing changes. The rest of the code snipet is available on pastie.org
Can anyone point out the oversight?
Thanks
Change Interceptor to SoapPreProtocolOutInterceptor. For details refer link
Hence modify the class as below.
public class HttpHeaderInterceptor extends SoapPreProtocolOutInterceptor {
public void handleMessage(SoapMessage message) throws Fault {
Map<String, List<String>> ietHeaders = new HashMap<String, List<String>>();
List<String> headerItems = new LinkedList<String>();
headerItems.add("h1");
headerItems.add("h2");
headerItems.add("h3");
ietHeaders.put("CustomHeader", headerItems);
message.put(Message.PROTOCOL_HEADERS, ietHeaders);
}
}
Modify your cxf-bean.xml to include interceptor
<jaxws:outInterceptors>
<bean class="com.kp.swasthik.soap.interceptor.HttpHeaderInterceptor" />
</jaxws:outInterceptors>
The output would be as below.
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
CustomHeader: h1,h2,h3
Content-Type: text/xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 12 Aug 2014 11:17:57 GMT

Resources