代码之家  ›  专栏  ›  技术社区  ›  George

Jersey Client无法通过JAXB Moxy序列化发送/接收XML消息?

  •  1
  • George  · 技术社区  · 9 年前

    我正在尝试使用jersey客户端使用XML消息发出一些RESTful请求。我不想为任何端点提供服务,因此不涉及球衣服务器包。
    出于测试目的,我使用了可公开访问的 http://www.thomas-bayer.com/sqlrest/CUSTOMER 测试服务。

    如中所述 9.2.4. Using Custom JAXBContext 我有一个自定义ContextResolver类,它是:

    @Provider
    @Produces({"application/xml"})
    public class MyJaxbContextProvider implements ContextResolver<JAXBContext> {
    
      private JAXBContext context;
    
      public JAXBContext getContext(Class<?> type) {
        if (context == null) {
          try {
            context = JAXBContext.newInstance("resttest.jaxb");
          } catch (JAXBException e) {
            throw new RuntimeException(e);
          }
        }
        return context;
      }
    }
    

    此ContextResolver在rest客户端中注册为:

    client = ClientBuilder.newClient().register(MoxyXmlFeature.class).register(MyJaxbContextProvider.class);
    

    我的客户实体是:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "id",
        "firstname",
        "lastname",
        "street",
        "city"
    })
    @XmlRootElement(name = "CUSTOMER")
    public class Customer {
      @XmlElement(name = "ID")
      protected Integer id;
    
      @XmlElement(name = "FIRSTNAME")
      protected String firstName;
    
      @XmlElement(name = "LASTNAME")
      protected String lastName;
    
      @XmlElement(name = "STREET")
      protected String street;
    
      @XmlElement(name = "CITY")
      protected String city;
    
      // getters and setters following
      // ...
    }
    

    最后,发出实际请求的测试类是:

    public class RestClientTest {
      private static Client client;
    
      @BeforeClass
      public static void beforeClass() {
        client = ClientBuilder.newClient().register(MoxyXmlFeature.class).register(MyJaxbContextProvider.class);
      }
    
      @Test
      public void testCreateCustomerWithEntity() { // Error
        Customer customer = new Customer();
        customer.setId(50);
        customer.setFirstName("Nikol");
    
        Response res = client.target("http://www.thomas-bayer.com/sqlrest/CUSTOMER/").request()
            .post(entity(customer, MediaType.APPLICATION_XML_TYPE));
    
      }
    
      @Test
      public void testGetCustomer() { // Error
        Customer customer = client.target("http://www.thomas-bayer.com/sqlrest/CUSTOMER/3/").request()
            .get(new GenericType<Customer>() {});
    
        assertThat(customer.getId(), equalTo(3));
      }
    }
    

    我已将这些文件打包到位于的resttest项目中 https://github.com/georgeyanev/resttest
    克隆后,只需使用

    mvn test
    

    我希望当我发出POST请求并传递一个Customer实例时,后者将由jersey客户端(testCreateCustomerWithEntity)整理。
    当我发出GET请求时,返回的Customer实体将被解组(testGetCustomer)。
    但这两个测试都失败,MessageBodyProviderNotFoundException表示没有为媒体类型application/xml和类型Customer找到MessageBodyWriter/MessageBodyReader。

    我使用的是2.19版本的jersey客户端和jersey媒体moxy库以及oracle java 1.8.0_25

    可能的原因是什么?

    1 回复  |  直到 9 年前
        1
  •  1
  •   George    9 年前

    为了让jersey选择自定义ContextResolver,似乎需要对jersey媒体jaxb的附加依赖。然后使用标准JAXB机制定义JAXBContextFactory,从中可以获得JAXBContext实例。
    在这种情况下,JAXBContextFactory类在 jaxb.properties 中的文件 resttest.jaxb 包裹