Aah,

So in order to make this work through CXF is to define an EntitiesListWrapper class. Right? Then the ParamConverter will be called with EntitiesListWrapper as argument and jackson will deserialize. Right?

Is there any other way to break the input of
final String entities_json = "[{\"name\":\"cca1\", \"type\":\"GENE\"},{\"name\":\"cca2\", \"type\":\"GENE\"}]";
so the paramconverter will be called with the correct substring each time?

This looks weird.

    Vassilis


On 08/12/2014 06:22 PM, Sergey Beryozkin wrote:
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




--

__________________________________

Vassilis Virvilis Ph.D.
Head of IT
Biovista Inc.

US Offices
2421 Ivy Road
Charlottesville, VA 22903
USA
T: +1.434.971.1141
F: +1.434.971.1144

European Offices
34 Rodopoleos Street
Ellinikon, Athens 16777
GREECE
T: +30.210.9629848
F: +30.210.9647606

www.biovista.com

Biovista is a privately held biotechnology company that finds novel uses for existing drugs, and profiles their side effects using their mechanism of action. Biovista develops its own pipeline of drugs in CNS, oncology, auto-immune and rare diseases. Biovista is collaborating with biopharmaceutical companies on indication expansion and de-risking of their portfolios and with the FDA on adverse event prediction.


Reply via email to