[ 
https://issues.apache.org/jira/browse/CAMEL-15370?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17172230#comment-17172230
 ] 

Bernhard Unger edited comment on CAMEL-15370 at 8/6/20, 10:43 AM:
------------------------------------------------------------------

Hi Chandrakant,

Spring MVC ist using a "MultiValueMap" to solve this problem. See 
[https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/MultiValueMap.html]

Also available from google commons is com.google.common.collect.HashMultimap

These maps simply allowing multiple identical keys.

I think this could be a possibility for fixing the problem.

We implemented a workarround so far:
{code:java}
private HashMultimap<String, String> createParamsMultimap(String queryString, 
String charset)
                        throws UnsupportedEncodingException {
                HashMultimap<String, String> queryMap = HashMultimap.create();


                for (String param : queryString.split("&")) {
                        String[] pair = param.split("=", 2);
                        if (pair.length == 2) {
                                String name = URLDecoder.decode(pair[0], 
charset);
                                String value = URLDecoder.decode(pair[1], 
charset);
                                queryMap.put(name, value);
                        }
                        else {
                                throw new IllegalArgumentException("Invalid 
parameter, expected to be a pair but was " + param);
                        }
                }

                return queryMap;
        }
{code}
Disadvantage indeed is, that we must implement a new Map Interface, otherwise 
we would break Camels API.

{code:java}
// New implementation
static class MyMultiMap implements Map<String, String> {
...
//All other Methots throwing an UnsupportedOperationException
@Override
                public Set<Entry<String, String>> entrySet() {
                        return mulitmap.entries();
                }
{code}
In process Method:

{code:java}
@Override
        public void process(Exchange exchange) throws Exception {
                String queryString = 
exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);

                // create multimap of parameters, preserving multiple params of 
the same name
                HashMultimap<String, String> queryMap =
                                createParamsMultimap(queryString, 
ExchangeHelper.getCharsetName(exchange));

                // wrap it to hide the multimap als a conventional map
                MyMultiMap myMultiMap = new MyMultiMap(queryMap);

                // set override parameter for cxf query map
                
exchange.getMessage().setHeader(CxfConstants.CAMEL_CXF_RS_QUERY_MAP, 
myMultiMap);
//further implementations....
{code}


Maybe you find a cleaner backward compatible way for the fix?

Kind regards

Bernhard


was (Author: [email protected]):
Hi Chandrakant,

Spring MVC ist using a "MultiValueMap" to solve this problem. See 
[https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/MultiValueMap.html]

Also available from google commons is com.google.common.collect.HashMultimap

These maps simply allowing multiple identical keys.

I think this could be a possibility for fixing the problem.

We implemented a workarround so far:
{code:java}
private HashMultimap<String, String> createParamsMultimap(String queryString, 
String charset)
                        throws UnsupportedEncodingException {
                HashMultimap<String, String> queryMap = HashMultimap.create();


                for (String param : queryString.split("&")) {
                        String[] pair = param.split("=", 2);
                        if (pair.length == 2) {
                                String name = URLDecoder.decode(pair[0], 
charset);
                                String value = URLDecoder.decode(pair[1], 
charset);
                                queryMap.put(name, value);
                        }
                        else {
                                throw new IllegalArgumentException("Invalid 
parameter, expected to be a pair but was " + param);
                        }
                }

                return queryMap;
        }
{code}
Disadvantage indeed is, that we must implement a new Map Interface, otherwise 
we would break Camels API.

{code:java}
// New implementation
static class MyMultiMap implements Map<String, String> {
...
//All other Methots throwing an UnsupportedOperationException
@Override
                public Set<Entry<String, String>> entrySet() {
                        return mulitmap.entries();
                }
{code}


Maybe you find a cleaner backward compatible way for the fix?

Kind regards

Bernhard

> CxfRsProducer: All but last value of query parameter with multiple values are 
> lost
> ----------------------------------------------------------------------------------
>
>                 Key: CAMEL-15370
>                 URL: https://issues.apache.org/jira/browse/CAMEL-15370
>             Project: Camel
>          Issue Type: Bug
>          Components: came-cxf
>    Affects Versions: 3.3.0
>            Reporter: Frank Denninger
>            Assignee: Freeman Yue Fang
>            Priority: Major
>             Fix For: 3.5.0
>
>         Attachments: CAMEL-15370.patch, CAMEL-15370_Chandra.patch
>
>
> If using a query parameter name multiple times, only the last value is 
> actually used.
>  
> e.g.  .to("cxfrs:[http://example.com/]";) with Exchange value 
> Exchange.HTTP_QUERY id=1&id=2 will call to example.com with id=2
>  
> As far as i can tell the problem is caused by 
> CxfRsProducer::getQueryParametersFromQueryString. In the method all query 
> paramters are inserted in a map, and only the last use of a parameter name is 
> preserved.
>  
> One solution would be to insert the values directy into the client field, 
> skipping the Map.
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to