CXF: WARNING: No message body writer has been found for response class ArrayList

StackOverflow https://stackoverflow.com/questions/23177487

  •  06-07-2023
  •  | 
  •  

Вопрос

I'm getting the following error:

WARNING: No message body writer has been found for response class ArrayList.

On the following code:

    @GET
    @Consumes("application/json")
    public List getBridges() {
        return  new ArrayList(bridges);
    }

I know it's possible for CXF to handle this case because I've done it before - with a platform that defined the CXF and related maven artifacts behind the scenes (i.e. I didn't know how it was done).

So, the question: how can I get CXF to support this without adding XML bindings or other source code modifications?

Note the following answer addressed the same problem with XML bindings, which is not satisfactory for my case: No message body writer has been found for response class ArrayList

Это было полезно?

Решение

The problem turns out to be a simple missing Accept header:

Accept: application/json

Adding this to the request resolves the problem.

Другие советы

The best thing is indeed to use Jackson. The following post gives a great description of why and how to do it.

for your convinience I've summerized the main things:

You will need to set Jackson as the provider, the best way to do it is to use your custom Application overriding javax.ws.rs.core.Application

you will need to add the following code

@Override


  public Set<Object> getSingletons() {
        Set<Object> s = new HashSet<Object>();

        // Register the Jackson provider for JSON

        // Make (de)serializer use a subset of JAXB and (afterwards) Jackson annotations
        // See http://wiki.fasterxml.com/JacksonJAXBAnnotations for more information
        ObjectMapper mapper = new ObjectMapper();
        AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
        AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
        AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary);
        mapper.getDeserializationConfig().setAnnotationIntrospector(pair);
        mapper.getSerializationConfig().setAnnotationIntrospector(pair);

        // Set up the provider
        JacksonJaxbJsonProvider jaxbProvider = new JacksonJaxbJsonProvider();
        jaxbProvider.setMapper(mapper);

        s.add(jaxbProvider);
        return s;
      }

Finally, do not forget to add Jackson to your maven

<dependency>
      <groupId>org.glassfish.jersey.media</groupId>
      <artifactId>jersey-media-json-jackson</artifactId>
      <version>2.7</version>
      <scope>compile</scope>
</dependency>

Having the same problem I've finally solved it like this. In your Spring context.xml define bean:

<bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>

And use it in the <jaxrs:server> as a provider:

<jaxrs:server id="restService" address="/resource">
    <jaxrs:providers>
        <ref bean="jsonProvider"/>
    </jaxrs:providers>
</jaxrs:server>

In your Maven pom.xml add:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-jaxrs</artifactId>
    <version>1.9.0</version>
</dependency>

If you are using Jackson you can write custom message body writer.

public class KPMessageBodyWriter implements
        MessageBodyWriter<ArrayList<String>> {

    private static final Logger LOG = LoggerFactory.getLogger(KPMessageBodyWriter.class);
    public boolean isWriteable(Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {

        return true;
    }

    public long getSize(ArrayList<String> t, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {

        return t.size();
    }

    public void writeTo(ArrayList<String> t, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders,
            OutputStream entityStream) throws IOException,
            WebApplicationException {

        ObjectMapper mapper = new ObjectMapper();

            mapper.writeValue(entityStream, t);

    }

}

In cx configuration file add the provider

<jaxrs:providers>
     <bean class="com.kp.KPMessageBodyWriter" />
</jaxrs:providers>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top