[ 
https://issues.apache.org/jira/browse/CXF-2242?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12714709#action_12714709
 ] 

Nacho G. Mac Dowell commented on CXF-2242:
------------------------------------------

Oops... I forgot to include the other it.hasNext()...

Currently this test fails:

        MultivaluedMap<String, String> mvMap = new MetadataMap<String, 
String>();
        mvMap.add("a", "a1");
        mvMap.add("a", "a2");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ferp.writeTo(mvMap, MultivaluedMap.class, MultivaluedMap.class,
                     new Annotation[0], 
MediaType.APPLICATION_FORM_URLENCODED_TYPE,
                     new MetadataMap<String, Object>(), bos);
        String result = bos.toString();
        assertEquals("Wrong value", "a=a1&a=a2", result.toString());

The result is a=a1a=a2

So, it should be....:

        for (Iterator<Map.Entry<String, List<String>>> it = 
map.entrySet().iterator(); it.hasNext();) {
            Map.Entry<String, List<String>> entry = it.next();
            for (Iterator<String> entryIterator = entry.getValue().iterator(); 
entryIterator.hasNext();) {
                                String value = entryIterator.next();
                                os.write(entry.getKey().getBytes("UTF-8"));
                os.write('=');
                String data = encoded ? value : HttpUtils.urlEncode(value);
                os.write(data.getBytes("UTF-8"));
                if (entryIterator.hasNext() || it.hasNext()) {
                    os.write('&');
                }
        }
}
 
Like this, your test, the prev test and the following will pass:

        MultivaluedMap<String, String> mvMap = new MetadataMap<String, 
String>();
        mvMap.add("a", "a1");
        mvMap.add("b", "b1");
        mvMap.add("b", "b2");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ferp.writeTo(mvMap, MultivaluedMap.class, MultivaluedMap.class,
                     new Annotation[0], 
MediaType.APPLICATION_FORM_URLENCODED_TYPE,
                     new MetadataMap<String, Object>(), bos);
        String result = bos.toString();
        assertEquals("Wrong value", "a=a1&a=a2", result.toString());

Best regards,
n

> FormEncodingProvider writes the application/x-www-form-urlencoded params 
> incorrectly when multiple params with the same name are present
> ----------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CXF-2242
>                 URL: https://issues.apache.org/jira/browse/CXF-2242
>             Project: CXF
>          Issue Type: Bug
>          Components: REST
>    Affects Versions: 2.2.1
>            Reporter: Nacho G. Mac Dowell
>         Attachments: FormEncodingProvider.patch
>
>
> Hi, there is a problem with FormEncodingProvider when writing the url-encoded 
> string. It is checking an incorrect iterator.
>     public void writeTo(MultivaluedMap<String, String> map, Class<?> c, Type 
> t, Annotation[] anns, 
>                         MediaType mt, MultivaluedMap<String, Object> headers, 
> OutputStream os) 
>         throws IOException, WebApplicationException {
>         boolean encoded = AnnotationUtils.getAnnotation(anns, Encoded.class) 
> != null;
>         for (Iterator<Map.Entry<String, List<String>>> it = 
> map.entrySet().iterator(); it.hasNext();) {
>             Map.Entry<String, List<String>> entry = it.next();
>             for (String value : entry.getValue()) {
>                 os.write(entry.getKey().getBytes("UTF-8"));
>                 os.write('=');
>                 String data = encoded ? value : HttpUtils.urlEncode(value); 
>                 os.write(data.getBytes("UTF-8"));
>                 if (it.hasNext()) {
>                     os.write('&');
>                 }
>             }
>         }
>     }
> it.hasNext() should be checking the entry iterator and not the map iterator. 
> The consequence is that & is never appended if, for example, there is only 
> one parameter
> Fixed version would be:
>     public void writeTo(MultivaluedMap<String, String> map, Class<?> c, Type 
> t, Annotation[] anns, 
>                         MediaType mt, MultivaluedMap<String, Object> headers, 
> OutputStream os) 
>         throws IOException, WebApplicationException {
>         boolean encoded = AnnotationUtils.getAnnotation(anns, Encoded.class) 
> != null;
>         for (Iterator<Map.Entry<String, List<String>>> it = 
> map.entrySet().iterator(); it.hasNext();) {
>             Map.Entry<String, List<String>> entry = it.next();
>             for (Iterator<String> entryIterator = 
> entry.getValue().iterator(); entryIterator.hasNext();) {
>               String value = entryIterator.next();
>                               os.write(entry.getKey().getBytes("UTF-8"));
>                 os.write('=');
>                 String data = encoded ? value : HttpUtils.urlEncode(value); 
>                 os.write(data.getBytes("UTF-8"));
>                 if (entryIterator.hasNext()) {
>                     os.write('&');
>                 }
>             }
>         }
>     }
> I don't have time just now to provide test cases but a careful look should do.
> best regards

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to