1

私はこの問題に何日も悩まされており、現在、問題の解決に役立つガイダンスを探しています. Metro で jax-ws を使用した経験はかなりありますが、Jersey で jax-rs を使用するのはこれが初めてです。可動部分を単純化するために、jersey-examples-moxy コードを出発点として取り上げました。

サンプル プロジェクトを変更して、XML と JSON の両方を受け入れるようにしました。これは簡単なことだと思っていたのですが、辛い経験をしたので何かが足りないようです。「application/xml」をリクエストしているときにコードは問題なく実行され、GET は「application/json」に対して機能しますが、JSON で PUT を実行しようとすると、サーバーは 500 ステータス コードを返します。JSON が PUT リクエストで送信されていることがわかりますが、サーバーで JSON の受け入れに問題があるようです。

これは、変更された CustomerResource.java ファイル セグメントです。MediaType.APPLICATION_JSON パラメータを Produces および Consumes アノテーションに追加しただけです。

@Path("/customer")
public class CustomerResource {

  private static Customer customer = createInitialCustomer();

  @GET
  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
  public Customer getCustomer() {
    return customer;
  }

  @PUT
  @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
  public void setCustomer(Customer c) {
    customer = c;
  }

  private static Customer createInitialCustomer() {
    Customer result = new Customer();

    result.setName("Jane Doe");
    result.setAddress(new Address("123 Any Street", "My Town"));
    result.getPhoneNumbers().add(new PhoneNumber("work", "613-555-1111"));
    result.getPhoneNumbers().add(new PhoneNumber("cell", "613-555-2222"));

    return result;
  }
}

MoxyAppTest.java ファイルを変更して、別々のテストで XML と JSON の MediaType を要求するようにしました。

@Test
public void testJaxBCustomer() throws Exception {
    final WebTarget webTarget = target().path("customer");

    Customer customer = webTarget.request(MediaType.APPLICATION_XML).get(Customer.class);
    assertEquals("Jane Doe", customer.getName());

    customer.setName("Tom Dooley");
    Response response = webTarget.request(MediaType.APPLICATION_XML).put(Entity.xml(customer));
    assertEquals(204, response.getStatus());

    Customer updatedCustomer = webTarget.request(MediaType.APPLICATION_XML).get(Customer.class);
    assertEquals(customer, updatedCustomer);
}

@Test
public void testJsonCustomer() throws Exception {
    final WebTarget webTarget = target().path("customer");

    Customer customer = webTarget.request(MediaType.APPLICATION_JSON).get(Customer.class);
    assertEquals("Tom Dooley", customer.getName());

    customer.setName("Bobby Boogie");
    Response response = webTarget.request(MediaType.APPLICATION_JSON).put(Entity.json(customer));
    assertEquals(204, response.getStatus());

    Customer updatedCustomer = webTarget.request(MediaType.APPLICATION_JSON).get(Customer.class);
    assertEquals(customer, updatedCustomer);
}

App.java ファイルでは、JsonMoxyConfigurationContextResolver クラスと createApp() メソッドでの registerInstances() 呼び出しを追加しました。(これを取り出しても結果は変わらないことに注意してください)。

public static ResourceConfig createApp() {
    return new ResourceConfig().packages("org.glassfish.jersey.examples.xmlmoxy")
            .register(new MoxyXmlFeature())
            .registerInstances(new JsonMoxyConfigurationContextResolver());      
}

@Provider
final static class JsonMoxyConfigurationContextResolver implements ContextResolver<MoxyJsonConfig> {

    @Override
    public MoxyJsonConfig getContext(Class<?> objectType) {
        final MoxyJsonConfig configuration = new MoxyJsonConfig();

        Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
        namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");

        configuration.setNamespacePrefixMapper(namespacePrefixMapper);
        configuration.setNamespaceSeparator(':');

        return configuration;
    }
}

以下は、「application/xml」PUT がステータス 204 で成功したことを示すログ セグメントです。

Aug 23, 2013 1:23:50 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 3 * LoggingFilter - Request received on thread main
3 > PUT http://localhost:9998/customer
3 > Accept: application/xml
3 > Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<customer><personal-info><name>Tom Dooley</name></personal-info><contact-info><address><city>My Town</city><street>123 Any Street</street></address><phone-number type="work">613-555-1111</phone-number><phone-number type="cell">613-555-2222</phone-number></contact-info></customer>

Aug 23, 2013 1:23:50 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 4 * LoggingFilter - Response received on thread main
4 < 204
4 < Date: Fri, 23 Aug 2013 05:23:50 GMT

「application/json」ログの場合:

Aug 23, 2013 1:23:51 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 3 * LoggingFilter - Request received on thread main
3 > PUT http://localhost:9998/customer
3 > Accept: application/json
3 > Content-Type: application/json
{"personal-info":{"name":"Bobby Boogie"},"contact-info":{"address":{"city":"My Town","street":"123 Any Street"},"phone-number":[{"type":"work","value":"613-555-1111"},{"type":"cell","value":"613-555-2222"}]}}

Aug 23, 2013 1:23:51 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 4 * LoggingFilter - Response received on thread main
4 < 500
4 < Date: Fri, 23 Aug 2013 05:23:50 GMT
4 < Content-Length: 0
4 < Connection: close

ご覧のとおり、サーバーはステータス コード 500 を返しています。Grizzly テスト コンテナーは、例外情報をキャプチャするログを生成しておらず、500 応答で何も返されていないようです。追加の例外の詳細を取得する方法はありますか?

続行する方法について何か提案はありますか?

ありがとうございました!

4

1 に答える 1