找不到Java类型的消息正文编写器

时间:2016-05-28 06:16:11

标签: web-services rest java-ee jersey jax-rs

我收到以下异常:

  

ClientHandlerException:Java类型的消息体编写器,
  class com.company.testing.repo.model.Privilege,
  和MIME媒体类型,   application / octet-stream,未找到

Privilege是一个ENUM类:

public enum Privilege {
    READ,
    WRITE;
}

资源条目是:

@Path("repoPrivs")
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    Response getGroups(Privilege privilege);

我的客户端代码是:

@Override
public List<MyGroup> getGroups(Privilege privilege) {
                IWebParamaterProvider provider = WebParamaterFactory.create("repo-mapping/repoPrivs", //$NON-NLS-1$
                SecureAction.READ, webProxy);
        provider = provider.setType(MediaType.APPLICATION_JSON);
        provider = provider.setAccept(MediaType.APPLICATION_JSON);
        List<MyGroup> groups = null;
        groups = webProxy.post(provider, new GenericTypeFactory<MyGroup>(), MyGroup.class, privilege);
        return groups;
    }

Override
public final <T> List<T> post(IWebParamaterProvider provider, GenericTypeFactory<T> genericsFactory,
        Class<T> clazz, Object requestEntity){
WebResource resource = ((IWebResourceProvider) provider).getWebResource();
TRACER.trace("POST: " + resource.getURI().toString()); //$NON-NLS-1$
return resource.post(genericsFactory.create(clazz), requestEntity);

}

public GenericType<List<T>> create(final Class<T> clazz) {

    ParameterizedType genericType = new ParameterizedType() {
        @Override
        public Type[] getActualTypeArguments() {
            return new Type[] { clazz };
        }

        @Override
        public Type getOwnerType() {
            return List.class;
        }

        @Override
        public Type getRawType() {
            return List.class;
        }
    };

    return new GenericType<List<T>>(genericType) {
    };
}

我错过了什么

2 个答案:

答案 0 :(得分:1)

提供完整的最小示例非常重要,以便其他人可以帮助您。

下面你有Jersey 2和Jersey 1的例子,它们都在内存测试容器中使用。确保根据版本获得所有必需的依赖项。

泽西2

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.Test;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.junit.Assert.*;

public class JerseyVersion2Test extends JerseyTest {

  @Path("hello")
  public static class HelloResource {

    @POST
    @Produces(APPLICATION_JSON)
    @Consumes(APPLICATION_JSON)
    public List<MyGroup> doPost(Privilege privilege) {
      List<MyGroup> myGroups = new ArrayList<>();
      MyGroup myGroup = new MyGroup();
      myGroup.name = "jersey";
      myGroup.version = 2;
      myGroups.add(myGroup);
      return myGroups;
    }

  }

  @Override
  protected Application configure() {
    return new ResourceConfig(HelloResource.class);
  }

  @Override
  protected TestContainerFactory getTestContainerFactory() {
    return new InMemoryTestContainerFactory();
  }

  @Test
  public void testPost() {
    List<MyGroup> myGroups = getGroups();
    assertEquals(1, myGroups.size());
  }

  public enum Privilege {
    READ,
    WRITE;
  }

  public List<MyGroup> getGroups() {
    List<MyGroup> groups = target("hello").request().
            accept(MediaType.APPLICATION_JSON).
            post(Entity.json(Privilege.READ)).
            readEntity(new GenericTypeFactory<MyGroup>().create(MyGroup.class));
    return groups;
  }

  @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
  public static class MyGroup {
    private String name;
    private double version;
  }

  public class GenericTypeFactory<T> {
    public GenericType<List<T>> create(final Class<T> clazz) {

      ParameterizedType genericType = new ParameterizedType() {
        @Override
        public Type[] getActualTypeArguments() {
          return new Type[]{clazz};
        }

        @Override
        public Type getOwnerType() {
          return List.class;
        }

        @Override
        public Type getRawType() {
          return List.class;
        }
      };

      return new GenericType<List<T>>(genericType) {
      };
    }
  }

}

泽西1

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.test.framework.AppDescriptor;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.LowLevelAppDescriptor;
import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
import com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory;
import org.junit.Test;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.junit.Assert.assertEquals;

public class JerseyVersion1Test extends JerseyTest {
  @Path("hello")
  public static class HelloResource {

    @POST
    @Produces(APPLICATION_JSON)
    @Consumes(APPLICATION_JSON)
    public List<MyGroup> doPost(Privilege privilege) {
      List<MyGroup> myGroups = new ArrayList<>();
      MyGroup myGroup = new MyGroup();
      myGroup.name = "jersey";
      myGroup.version = 1.12;
      myGroups.add(myGroup);
      return myGroups;
    }

  }

  @Override
  protected AppDescriptor configure() {
    return new LowLevelAppDescriptor.Builder(HelloResource.class).build();
  }

  @Override
  protected TestContainerFactory getTestContainerFactory() {
    return new InMemoryTestContainerFactory();
  }

  @Test
  public void testPost() {
    List<MyGroup> myGroups = getGroups();
    assertEquals(1, myGroups.size());
  }

  public enum Privilege {
    READ,
    WRITE;
  }

  public List<MyGroup> getGroups() {
    WebResource webResource = resource();
    List<MyGroup> groups = webResource.path("hello").
            accept(MediaType.APPLICATION_JSON).
            type(MediaType.APPLICATION_JSON).
            post(new GenericTypeFactory<MyGroup>().create(MyGroup.class), Privilege.READ);
    return groups;
  }

  @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
  public static class MyGroup {
    private String name;
    private double version;
  }

  public class GenericTypeFactory<T> {
    public GenericType<List<T>> create(final Class<T> clazz) {

      ParameterizedType genericType = new ParameterizedType() {
        @Override
        public Type[] getActualTypeArguments() {
          return new Type[]{clazz};
        }

        @Override
        public Type getOwnerType() {
          return List.class;
        }

        @Override
        public Type getRawType() {
          return List.class;
        }
      };

      return new GenericType<List<T>>(genericType) {
      };
    }
  }
}

答案 1 :(得分:0)

javax.xml.bind.annotation.XmlRootElement

Java doc:

  

@XmlRootElement注释可以与以下程序一起使用   要素:

     
      
  • 顶级课程
  •   
  • 枚举类型

         

    [...]

  •   
     

当使用@XmlRootElement批注对顶级类或枚举类型进行批注时,其值在XML文档中表示为XML元素。

在你的情况下,很明显泽西岛无法将传入的JSON有效负载解组到你的对象,因此异常

Java类型的消息正文编写器,类com.company.testing.repo.model。权限

使用@XmlRootElement注释您的Enum(权限)应该可以解决问题。

(<rx.linq.groupedobservable.GroupedObservable object at 0x0313EB10>, 2)