Hi Jean,

My apologies for late response but it seems like you have found the issue :-). 
However 
am a bit surprised by the way you are using Content-Encoding [1]. I would 
expect the 
charset to be passed along with content type:

    Response
         .status(Status.OK)
         .entity(dvlInfo)
         .type(MediaType.APPLICATION_JSON_TYPE.withCharset("UTF-8"))
         .build();

But not as Content-Encoding header which seems to be not strictly correct usage 
[2].
Hope it makes sense, thank you.

[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
[2] 
https://stackoverflow.com/questions/17154967/is-content-encoding-being-set-to-utf-8-invalid

Best Regards,
    Andriy Redko


JPU> Hi andriy,

JPU> As far as I could trace this the problem seems to be with the logging of 
the
JPU> incoming response message only.

JPU> In the method HttpConduit#handleResponseInternal the inMessage has:

JPU>         
org.apache.cxf.message.Message.PROTOCOL_HEADERS={content-encoding=[UTF-8],
JPU> Content-Length=[841], content-type=[application/json], Date=[Tue, 16 May
JPU> 2023 10:23:41 GMT], Server=[Jetty(9.4.46.v20220331)]}

JPU> But the call to "updateResponseHeaders(inMessage)" only examines the
JPU> 'content-type' protocol header not the 'content-encoding' header. So the
JPU> inMessage will not have set the 'Message.CONTENT_TYPE' as a result the
JPU> subsequent line of code (line 1682):

JPU>         String charset =
JPU> HttpHeaderHelper.findCharset((String)inMessage.get(Message.CONTENT_TYPE));

JPU> returns 'null' resulting in normalizedEncoding=ISO-8859-1.


JPU> Is this a bug?

JPU> J.P.

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>
JPU> Sent: maandag 15 mei 2023 16:46
JPU> To: 'Andriy Redko' <drr...@gmail.com>
JPU> Subject: Mismatch in content encoding between client and server

JPU> Hi Andriy,

JPU> I got my services installed but when performing some local (JUnit) tests I
JPU> notice that I am losing the content-encoding.

JPU> E.g. in below message logging from CXF the country 'België' is passed in 
the
JPU> response which has the header content-encoding=UTF-8 set.
JPU> When reading/parsing the response it results in ' België' ?

JPU> What does the server/client need to do to make sure the content is 
correctly
JPU> encoded/decoded when:
JPU>  - the server writes the result entity in the reponse  (I used
JPU> 
"Response.status(Status.OK).entity(dvlInfo).type(MediaType.APPLICATION_JSON).encoding("UTF-8").build()")
JPU>  - the client reads the result entity from the response (I didn't directly
JPU> see anything to inform the reader that the content is UTF-8 encoded so it 
is
JPU> currently read by the client as "resp.readEntity(Dienstverlener.class)")


JPU> Below the CXF message logging:

JPU> KMOP] 2023-05-15 16:29:38,503 [main] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - REQ_OUT
JPU>     Address:
JPU> 
http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     HttpMethod: GET
JPU>     Content-Type: application/json
JPU>     ExchangeId: 569ef415-99f7-41c2-956e-38e47ea8e4e5
JPU>     Headers: {Accept=application/json,
JPU> X-KMO-OPERATION-ID=ceaa4c95-0677-4510-b574-d99d82a45545,
JPU> Content-Type=application/json}

JPU> [KMOP] 2023-05-15 16:29:38,745 [qtp1348937989-29] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - REQ_IN
JPU>     Address:
JPU> 
http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     HttpMethod: GET
JPU>     Content-Type: application/json
JPU>     ExchangeId: 0c78ff64-8016-4809-adf8-691d786d0dfd
JPU>     Headers: {Accept=application/json, Cache-Control=no-cache,
JPU> User-Agent=Apache-CXF/3.5.2,
JPU> X-KMO-OPERATION-ID=ceaa4c95-0677-4510-b574-d99d82a45545,
JPU> connection=keep-alive, content-type=application/json, Host=localhost:8185,
JPU> Pragma=no-cache}

JPU> [KMOP] 2023-05-15 16:29:38,751 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBPoolManager:192) - Getting DBase connection from
JPU> DBPoolManager for DataSource name=DEFAULT_DS [KMOP] 2023-05-15 16:29:38,752
JPU> [qtp1348937989-29] DEBUG $--$ (be.xm.base.database.DBPoolManager:195) -
JPU> Found DataSource=oracle.jdbc.pool.OracleDataSource@77be656f for DataSource
JPU> name=DEFAULT_DS [KMOP] 2023-05-15 16:29:39,091 [qtp1348937989-29] DEBUG 
$--$
JPU> (be.xm.base.database.DBPoolManager:202) - Obtained DBase
JPU> connection(1995619431,autoCommit=true) from datasource DEFAULT_DS in
JPU> 338.9987 milliseconds.
JPU> [KMOP] 2023-05-15 16:29:39,346 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBHelper:386) - executed SQL-query
JPU> 'selDvlInfoForMMByErkNrAsJson' : obtained DBase resultset in 190.5721
JPU> milliseconds.
JPU> [KMOP] 2023-05-15 16:29:39,352 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBHelper:395) - executed SQL-query
JPU> 'selDvlInfoForMMByErkNrAsJson' : processed DBase resultset (1st record) in
JPU> 5.4814 milliseconds.
JPU> [KMOP] 2023-05-15 16:29:39,352 [qtp1348937989-29] DEBUG $--$
JPU> (be.xm.base.database.DBHelper:433) - Closing DBase
JPU> connection(1995619431,autoCommit=true)
JPU> [KMOP] 2023-05-15 16:29:39,391 [qtp1348937989-29] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - RESP_OUT
JPU>     Address:
JPU> 
http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     Content-Type: application/json
JPU>     ResponseCode: 200
JPU>     ExchangeId: 0c78ff64-8016-4809-adf8-691d786d0dfd
JPU>     Headers: {Content-Encoding=UTF-8, Date=Mon, 15 May 2023 14:29:39 GMT,
JPU> Content-Type=application/json}
JPU>     Payload: {"id":325943,"naam":"Qrios campus Aarschot","MZnaam":"QRIOS 
vzw
JPU> 
","kboNr":"0422695514","erkenningen":[{"dienst":"opleiding","nummer":"DV.O235055","erkendTot":"9999-01-01"}],"themas":[100000,100002,100010,100011,102290,102291,102292],"beoordelingen":[{"dienst":"opleiding","aantalBeoordelingen":10,"score":4.5}],"adres":{"land":"België","postcode":"3200","gemeente":"Aarschot","straat":"Bekaflaan","huisNummer":"62","busNummer":null},"contact":{"contactPersoon":"Peter
JPU> 
Holsters","telNr":"003216551115","faxNr":null,"email":"aarsc...@qrios.be","website":"http://www.qrios.be"},"beschrijving":"Opleidingsverstrekker
JPU> opleidingen voor
JPU> 
volwassenen","banner":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op/dvl/banner_325943.png","logo":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op/dvl/logo_325943.png","latitude":50.98734451,"longitude":4.8472477}

JPU> [KMOP] 2023-05-15 16:29:39,399 [main] INFO  $--$
JPU> (org.slf4j.helpers.MarkerIgnoringBase:95) - RESP_IN
JPU>     Address:
JPU> 
http://localhost:8185/op/services/dienstverlener/dienstverlener/findErkendByErkNr?erkNr=DV.O235055
JPU>     Content-Type: application/json
JPU>     ResponseCode: 200
JPU>     ExchangeId: 569ef415-99f7-41c2-956e-38e47ea8e4e5
JPU>     Headers: {Server=Jetty(9.4.46.v20220331), content-encoding=UTF-8,
JPU> content-type=application/json, Content-Length=841, Date=Mon, 15 May 2023
JPU> 14:29:39 GMT}
JPU>     Payload: {"id":325943,"naam":"Qrios campus Aarschot","MZnaam":"QRIOS 
vzw
JPU> 
","kboNr":"0422695514","erkenningen":[{"dienst":"opleiding","nummer":"DV.O235055","erkendTot":"9999-01-01"}],"themas":[100000,100002,100010,100011,102290,102291,102292],"beoordelingen":[{"dienst":"opleiding","aantalBeoordelingen":10,"score":4.5}],"adres":{"land":"België","postcode":"3200","gemeente":"Aarschot","straat":"Bekaflaan","huisNummer":"62","busNummer":null},"contact":{"contactPersoon":"Peter
JPU> 
Holsters","telNr":"003216551115","faxNr":null,"email":"aarsc...@qrios.be","website":"http://www.qrios.be"},"beschrijving":"Opleidingsverstrekker
JPU> opleidingen voor
JPU> 
volwassenen","banner":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op/dvl/banner_325943.png","logo":"http://AEODEV.BE.DEVOTEAM.COM:8081/images/op/dvl/logo_325943.png","latitude":50.98734451,"longitude":4.8472477}

JPU> -----Original Message-----
JPU> From: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>
JPU> Sent: dinsdag 9 mei 2023 9:25
JPU> To: 'Andriy Redko' <drr...@gmail.com>
JPU> Subject: RE: How to setup multiple JAXRS server endpoints

JPU> Hi Andriy,

JPU> Both servers have not only differences in 'authorization' but also in
JPU> exception handling regarding mapping and validation errors that's why I
JPU> can't use the same JAX-RS server bean for them. I'll have a look at
JPU> customizing the swagger feature and will come back on it but for now 
getting
JPU> the server up-and-running is more important.

JPU> Regards,

JPU> J.P. Urkens

JPU> -----Original Message-----
JPU> From: Andriy Redko <drr...@gmail.com>
JPU> Sent: maandag 8 mei 2023 23:15
JPU> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>; CXF Dev List
JPU> <dev@cxf.apache.org>
JPU> Subject: Re: How to setup multiple JAXRS server endpoints

JPU> Hi Jean,

JPU> Indeed the way you would like to do that is somewhat tricky.

>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

JPU> This is one of the possible options but OpenAPI/Swagger gets confused for a
JPU> reason: the path is now implicit (not in the spec).
JPU> So how about this option:
JPU>  - use only one JAX-RS server (address "/")
JPU>  - host both resources but use @Path("accounts") and @Path("resources") on
JPU> them respectively

JPU> I see that for @Path("accounts") you need to apply the
JPU> "kmopApiAuthorizationFilter", that could be done using DynamicFeature [1],
JPU> [2]. If this is not the option and you would prefer to use 2 separate 
JAX-RS
JPU> servers, you may need to provide your own instance of Swagger2Customizer
JPU> [3], [4] which allows to transform the OpenAPI/Swagger on the fly. Please
JPU> let me know if that would it work for you, thank you.

JPU> [1]
JPU> 
https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/DynamicFeature.html
JPU> [2]
JPU> 
https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born-equal.html
JPU> [3]
JPU> 
https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger/Swagger2Customizer.html
JPU> [4] https://cxf.apache.org/docs/swagger2feature.html (has customizer
JPU> property)


JPU> Best Regards,
JPU>     Andriy Redko

>> Hi Andriy,
>> I am again getting into trouble with server endpoint declarations. Now
>> because I am adding additional JAX-RS endpoints.
>> The issue is with:
>> 1.      The 'address' attribute on the <jaxrs:server> declaration in
>> combination with
>> 2.      The 'url-pattern' for the CXFServlet declaration in the web.xml in
>> combination with
>> 3.      The @Path declaration in the interface class in combination with
>> 4.      The @Path declaration on the interface method in combination with
>> So what I had is that my web application deployed under baseUlr 'op' had
>> one JAXRS server endpoint with declarations like:
>> 1.      <jaxrs:server id="restServer" basePackages="be.dvtm.aeo.op.sodexo"
>> address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("accounts") on the public interface class
>> 4.      @Path("/{authorisationId}/customerFund") on the customerFund
>> interface method
>> A valid API call would thus be e.g.:
>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/custo
>> merFund
>> And this works correctly.
>> We're now introducing additional JAX-RS service endpoints and now I am
>> running into problems. This second endpoint was declared with:
>> 1.      <jaxrs:server id="resourceServer"
>> basePackages="be.dvtm.aeo.op.resources" address="/">
>> 2.      <url-pattern>/services/*</url-pattern>
>> 3.      @Path("resources") on the public interface class
>> 4.      @Path("/NACE") on the NACE interface method
>> So here a valid API call woud be:
>> https://<hostname>:<port>/op/services/resources/NACE.
>> The problem is that I can not declare two <jaxrs:server> entries with the
>> same ‘address’ as it throws the exception:
>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
>> There is an endpoint already running on /.
>>  So I tried changing the addresses to:
>> ·       address=”accounts” for the restServer
>> ·       address=”resources” for the resourceServer
>> But to keep the API-call URLs the same I removed the @Path declaration on
>> the interface classes. By doing so the <jaxrs:server> bean declarations no
>> longer loads successfully.
>> So I tried to keep the @Path declaration on the interface classes but
>> changed them to @Path(“”). That does seems to work except the swagger
>> stuff no longer correctly works.

>> So what is the decent way to setup multiple JAX-RS server endpoints where
>> each server has its own configuration regarding supported features:
>> ·       own validation
>> ·       own object and exception mappings
>> ·       own swagger file generation
>> ·       own logging (in separate file if possible)
>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in cooperation
>> with swager-ui v4.5.0.
>> Below the declarations of my endpoints <<...>> Thanks for any advice.
>> Regards,
>> J.P. Urkens

>> -----Original Message-----
>> From: Andriy Redko <drr...@gmail.com>
>> Sent: zaterdag 18 juni 2022 1:12
>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
>> iss...@cxf.apache.org; dev@cxf.apache.org
>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>> Correct, so in the relative form like address="/<something>", the JAX-RS
>> endpoint path would be:
>>     <baseUrl>/<servlet path
>> mapping>/<address>/[@ApplicationPath]/[@Path]
>> The @ApplicationPath is optional in this case.
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>> The JAX-WS is very different from JAX-RS, essentially the action comes
>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/ (@Path /
>> @ApplicationPath are not relevant there).

>>> Question: Because now address="/" is set for the jaxrs:server will it
>>> also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...
>> This is a good question, I have not done it myself but I think it should
>> work:
>> the servlet dispatches according to registered services, in this regard
>> JAX-RS and JAX-WS should not conflict. Does it work in your case? Thank
>> you.
>> Best Regards,
>>     Andriy Redko
>>> Hi Andriy,
>>> Using address="/" seems to work but still I don't understand how the
>>> following work together:
>>>  - path specification in servlet mapping for the CXF servlet
>>> (org.apache.cxf.transport.servlet.CXFServlet)
>>>  - the 'address' attribute on the jaxrs:server bean declaration
>>>  - the javax.ws.rs.Path or javax.jws.WebService annotation on the
>>> service API description Say I've two services with (relateive to the
>>> host) url's:
>>> 1. a jaxrs server  on url: '/<basePath>/services/service1'
>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>>> How do I configure above 3 aspects? Currently I have (working):
>>> 1.for the jaxrs:server endpoint:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/"
>>>                - @Path annotation: @Path("service1") 2.For the jaxws
>>> service endpoint:
>>>         - servlet path mapping: '/services/*' (JAXWS and JAXRS
>>> requests are handleb by the same CXF servle)
>>>                - jaxws:endpoint server address attribute:
>>> address="/service2"
>>>                - @WebService(name="service2") A correct request for
>>> '1' would be '/basePath>/services/service1/<ID>'.
>>> A correct request for '2' would be '/basePath>/services/service2'.
>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:
>>>         - the server address attribute
>>>         - The API annotation (@Path or @Webservice) The JAXWS server
>>> address attribute doesn't seem to interfere with the @Webservice
>>> annotation. While the jaxrs server address attribute does seem to
>>> interfere with the @Path annotation. I would have expected the jaxrs
>>> server aspects to be configured as:
>>>         - servlet path mapping: '/services/*'
>>>                - jaxrs-server address attribute: address="/service1"
>>>                - @Path annotation: @Path("service1") but then a valid
>>> request would be
>>>> /services/service1/service1/<ID>'.
>>> For both the 'address' attribute is relative to the servlet path.
>>> The @Path Javadoc mentions that this path is relative to the
>>> ApplicationPath which thus seems to be relative to the jaxrs-server
>>> address attribute. As for @Webservice it doesnn't seem to be url-path
>>> related.
>>> Question: Because now address="/" is set for the jaxrs:server will it
>>> also inspect requests targeted for the jaxws service as those
>>> requests have start with the same path '/<basePath>/services/...'.
>>> Albeit somewhat confusing.
>>> J.P.
>>> -----Original Message-----
>>> From: Andriy Redko <drr...@gmail.com>
>>> Sent: dinsdag 14 juni 2022 1:08
>>> To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>;
>>> iss...@cxf.apache.org; dev@cxf.apache.org
>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>> Indeed, the jaxrs:server does not expect address to be omitted, you
>>> could use the "/" (and I believe an empty string would also make it):
>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
>>> </jaxrs:server>

>>> Thank you.
>>> Hope it helps.
>>> Best Regards,
>>>     Andriy Redko

>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
>>>> declarations
>>>> like:
>>>>      <jaxrs:server id="restServer" basePackages="xxx">
>>>>            <jaxrs:serviceBeans>
>>>>                 <ref bean="TestApi" />
>>>>            </jaxrs:serviceBeans>
>>>>            <jaxrs:providers>
>>>>                 <…/>
>>>>            </jaxrs:providers>
>>>>            <jaxrs:features>
>>>>                 <… />
>>>>            </jaxrs:features>
>>>>            <jaxrs:inInterceptors>
>>>>                 <… />
>>>>            </jaxrs:inInterceptors>
>>>>            <jaxrs:outInterceptors>*
>>>>                 <**…**/>*
>>>>            </jaxrs:outInterceptors>*
>>>>      </jaxrs:server>




>>>> Here my “TestApi” bean interface is declared like:


>>>>       @Path("accounts")
>>>>        @Consumes(MediaType.*APPLICATION_JSON*)
>>>>        @Produces(MediaType.*APPLICATION_JSON*)
>>>>        public interface TestApi {
>>>>          …
>>>>        }


>>>> And CXF is triggered via a servlet configuration like:
>>>>      <servlet>
>>>>              <display-name>CXF Servlet</display-name>
>>>>              <servlet-name>CXFServlet</servlet-name>

>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle
>>>> t
-class>>>>>
>>>>        </servlet>
>>>>        <servlet-mapping>
>>>>              <servlet-name>CXFServlet</servlet-name>
>>>>              <url-pattern>/services/*</url-pattern>
>>>>        </servlet-mapping>




>>>> Because I’ve got the @Path declaration on the interface type I’ve
>>>> omitted the address=”accounts” attribute on the jaxrs:server
>>>> declaration since otherwise I noticed that the server would be
>>>> listening to /basepath/services/ accounts/accounts/…).


>>>> Now this configuration works perfectly, only when shutting down the
>>>> application server cxf calls
>>>>         ServerImpl#destroy()


>>>> which delegates (via Obeservable) to
>>>> AbstractHTTPDestination#deactivate()
>>>> which calls
>>>> registry.removeDestination(path).
>>>> This path is null (no ‘address’ specified on jaxrs:server
>>>> declaration) and results in a NPE on the registry Map.
>>>> This causes an unclean shutdown of my server.


>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?
>>>> How does the ‘address’ attribute on the jaxrs:server declaration
>>>> correctly interact with the @Path parameter on the API interface?

Reply via email to