Hi

AFAIK ParamConverterProvider is expected to be called once per every entity in the list.

Thanks, Sergey

On 12/08/14 16:12, Vassilis Virvilis wrote:
Hi,

Some time before I have started a thread with jackson and form
parameters in cxf
http://mail-archives.apache.org/mod_mbox/cxf-users/201406.mbox/%[email protected]%3E


Sergey suggested that I should use ParamConverterProvider.

I tried it today and it worked. Great.

Now I am trying the next step which is to pass List<Entity> instead of
Entity in the input. The problem is that my ParamConverterProvider is
not called with the actual input class as specified in the interface
(List<Entity>) but with plain Entity as you can see from the logs. It
then fails because due to
         *** Can not deserialize instance of
com.biovista.lib.datatype.Entity out of START_ARRAY token ****

INFO
com.biovista.ws.impl.jaxrs.JacksonJsonParamConverterProvider.getConverter(JacksonJsonParamConverterProvider.java:41):
**** called: arg0: class com.biovista.lib.datatype.Entity arg1: class
com.biovista.lib.datatype.Entity arg2:
[Ljava.lang.annotation.Annotation;@7f65ae66 providers:
org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders@63aea6a8
INFO
com.biovista.ws.impl.jaxrs.JacksonJsonParamConverterProvider.getConverter(JacksonJsonParamConverterProvider.java:44):
Annotation: @javax.ws.rs.FormParam(value=entities)

Here is my ParamConverterProvider


package com.biovista.ws.impl.jaxrs;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.ProcessingException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.codehaus.jackson.map.ObjectMapper;

@Provider
public class JacksonJsonParamConverterProvider implements
ParamConverterProvider {
     private final Log log = LogFactory.getLog(getClass());

     @Override
     public <T> ParamConverter<T> getConverter(final Class<T> rawType,
             final Type genericType, final Annotation[] annotations) {

         log.info("**** called: arg0: " + rawType + " arg1: " + genericType
                 + " arg2: " + annotations + " providers: " + providers);
         for (final Annotation annotation : annotations) {
             log.info("Annotation: " + annotation);
         }

         return new ParamConverter<T>() {
             @Override
             public T fromString(final String value) {
                 try {
                     log.info("Called for " + value);
                     return mapper.reader(rawType).readValue(value);
                 } catch(IOException e) {
                     throw new ProcessingException(e);
                 }
             }

             @Override
             public String toString(final T value) {
                 try {
                     return mapper.writer().writeValueAsString(value);
                 } catch(Exception e) {
                     throw new ProcessingException(e);
                 }
             }
         };
     }
}


How can I register different ParamConverterProvider for different input
types? Or is that List is handled specially? By jackson or CXF? In
jackson I just need to do
         final List<Entity> entities = mapper.readValue(entities_json,
             new TypeReference<List<Entity>>() {
             });

but I don't know how to do this from inside CXF. I am using CXF 3.0

     Thanks

Reply via email to